import Callout from 'components/Callout';
import {Tab} from 'nextra-theme-docs';

# Internationalization of Metadata & Route Handlers with the Next.js App Router

There are a few places in Next.js apps where you might need to apply internationalization outside of React components:

1. [Metadata API](https://nextjs.org/docs/app/building-your-application/optimizing/metadata)
2. [Metadata files](https://nextjs.org/docs/app/api-reference/file-conventions/metadata)
3. [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/router-handlers)

`next-intl/server` provides a set of [awaitable functions](/docs/environments/server-client-components#async-components) that can be used in these cases.

### Metadata API

To internationalize metadata like the page title, you can use functionality from `next-intl` in the [`generateMetadata`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata#generatemetadata-function) function that can be exported from pages and layouts.

```tsx filename="app/[locale]/layout.tsx"
import {getTranslations} from 'next-intl/server';

export async function generateMetadata({params: {locale}}) {
  const t = await getTranslations({locale, namespace: 'Metadata'});

  return {
    title: t('title')
  };
}
```

<Callout>
  By passing an explicit `locale` to the awaitable functions from `next-intl`,
  you can make the metadata handler eligable for [static
  rendering](/docs/getting-started/app-router#static-rendering).
</Callout>

### Metadata files

If you need to internationalize content within [metadata files](https://nextjs.org/docs/app/api-reference/file-conventions/metadata), such as an Open Graph image, you can call APIs from `next-intl` in the exported function.

```tsx filename="app/[locale]/opengraph-image.tsx"
import {ImageResponse} from 'next/og';
import {getTranslations} from 'next-intl/server';

export default async function OpenGraphImage({params: {locale}}) {
  const t = await getTranslations({locale, namespace: 'OpenGraphImage'});
  return new ImageResponse(<div style={{fontSize: 128}}>{t('title')}</div>);
}
```

### Route Handlers

You can use `next-intl` in [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) too. The `locale` can either be received from a search param, a layout segment or by parsing the `accept-language` header of the request.

```tsx filename="app/api/hello/route.tsx"
import {NextResponse} from 'next/server';
import {getTranslations} from 'next-intl/server';

export async function GET(request) {
  // Example: Receive the `locale` via a search param
  const {searchParams} = new URL(request.url);
  const locale = searchParams.get('locale');

  const t = await getTranslations({locale, namespace: 'Hello'});
  return NextResponse.json({title: t('title')});
}
```
